#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include "glutEngine.h"
#include "../Model/AppList.h"

void GlutEngine::init(GraphicEngine* ge, AppList* list, int* argc, char ** argv) {
  mask = false;
  local_ge = ge;
  state = IN_APP;
  _list = list;

  /* GLUT init */
  glutInit(argc, argv);
  glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);

  glutInitWindowSize(ge->getXRes(), ge->getYRes());
  glutCreateWindow("KiCTRL");
  glutFullScreen();
  glutSetCursor(GLUT_CURSOR_NONE);

  /* GLUT callbacks */
  glutDisplayFunc(glutDraw);
  glutKeyboardFunc(glutKeyboard);
  glutIdleFunc(glutIdle);

}

void GlutEngine::refresh() {
  glutPostRedisplay();
}

void GlutEngine::start() {
  glutMainLoop();
}

int GlutEngine::getTime() {
  return glutGet(GLUT_ELAPSED_TIME);
}

void GlutEngine::drawText(std::string text) {
  char currChar;
  glColor4ub(233, 128, 128, 0);
  //glTranslatef(0.0, 1.0, 1.1);
  for (unsigned int i = 0; i < text.size(); currChar = text.at(i++)) {
    //glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, currChar);
    glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, currChar);
  }
}

//void glPrintString(void *font, char *str)
//{
//  int i,l = strlen(str);
//
//  for(i=0; i<l; i++)
//  {
//    glutBitmapCharacter(font,*str++);
//  }
//}
/* 
 * GLUT callbacks
 */
void GlutEngine::glutDraw(void) {
  // This functions works as a state machine
  local_ge->commonGL();
  switch (state) {
  case IN_APP:
    local_ge->draw();
    break;
  case ROTATING_RIGHT:
    local_ge->drawRotateRight();
    break;
  case ROTATING_LEFT:
    local_ge->drawRotateLeft();
    break;
  }
  local_ge->drawDock();
  //glColor3f(1., 1., 1.);
  //glTranslatef(0, 4, 4);
  glFlush();

  glutSwapBuffers();
}

void GlutEngine::glutIdle(void) {
  // TODO : optimize function to call it only if necessary
  glutPostRedisplay();
}

void GlutEngine::glutKeyboard(unsigned char key, int x, int y) {
  local_ge->activateSession();
  if (!mask) {
    switch (key) {
    case 27:
      exit(0);
    case '+':
      break;
    case '-':
      break;
    case 'n':
      local_ge->rotateLeft();
      GlutEngine::refresh();
      _list->swapNext();
      break;
    case 'p':
      local_ge->rotateRight();
      GlutEngine::refresh();
      _list->swapPrec();
      break;
    default:
      break;
    }
  }
}

AppList* GlutEngine::_list;
GraphicEngine* GlutEngine::local_ge;
WindowEngine::DrawState GlutEngine::state;
bool GlutEngine::mask;
